'use client';

import { type ChangeEvent, type FormEvent, useEffect, useState } from 'react';
import { useMutation, useQuery } from '@tanstack/react-query';
import {
  querySubmenuDetails,
  removeSubmenu,
  updateSubmenu,
} from '@/services/api';
import type { TMenuMenuType } from '@/types';
import type { IDifference, IMenu, ISubmenu } from '@/interfaces';
import diff from 'microdiff';
import useToast from '@/hooks/useToast';
import { getDiffData } from '@/lib/tool';
import Spinner from '@/app/[locale]/component/spinner/spinner';
import Box from '@/app/[locale]/admin/common/box';
import Nodata from '@/app/[locale]/common/nodata/nodata';
import type { PrefixedTTranslatedFields } from '@/lib/dictionaries';

export default function UpdateMenuSubmenu(
  this: any,
  {
    source,
    translatedFields,
  }: {
    source: IMenu;
    translatedFields: PrefixedTTranslatedFields<'menuAdminPage'>;
  },
) {
  const { show } = useToast();
  const [currentSubmenuItem, setCurrentSubmenuItem] = useState<ISubmenu>();
  const [currentRemoveSubmenuItem, setCurrentRemoveSubmenuItem] =
    useState<ISubmenu>();
  const [form, setForm] = useState<{
    name: string;
    path: string;
    sort: number;
    menuType: TMenuMenuType;
  }>({
    name: '',
    path: '',
    sort: 0,
    menuType: 'LINK',
  });
  const [differenceData, setDifferenceData] = useState<IDifference[]>([]);
  const [isDisabledSave, setIsDisabledSave] = useState(true);

  const querySubmenuDetailsQuery = useQuery(
    ['/submenus', currentSubmenuItem],
    async (context) => {
      return (await querySubmenuDetails({
        id: context.queryKey[1] + '',
      })) as ISubmenu;
    },
    {
      enabled: !!currentSubmenuItem,
    },
  );

  const updateSubmenuMutation = useMutation(updateSubmenu);
  const removeSubmenuMutation = useMutation(removeSubmenu);

  useEffect(() => {
    const diffData = diff(
      {
        name: querySubmenuDetailsQuery.data?.name ?? '',
        path: querySubmenuDetailsQuery.data?.path ?? '',
        sort: querySubmenuDetailsQuery.data?.sort ?? 0,
        menuType: querySubmenuDetailsQuery.data?.menuType ?? 'LINK',
      },
      form,
    );
    setDifferenceData(diffData);
    setIsDisabledSave(diffData.length === 0);
  }, [form, querySubmenuDetailsQuery.data]);

  async function onClickRemove(item: ISubmenu) {
    try {
      setCurrentRemoveSubmenuItem(item);

      const id = item.id + '';
      await removeSubmenuMutation.mutateAsync({
        id,
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.operate.deleteCompleted,
      });
    } catch (e) {
      removeSubmenuMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setCurrentRemoveSubmenuItem(undefined);
    }
  }

  async function onSubmit(e: FormEvent<HTMLFormElement>) {
    try {
      e.preventDefault();
      e.stopPropagation();

      if (source.submenus.length === 0 || !currentSubmenuItem) {
        return;
      }

      const data = getDiffData(differenceData);
      const id = currentSubmenuItem.id;
      await updateSubmenuMutation.mutateAsync({
        id,
        data,
      });

      show({
        type: 'SUCCESS',
        message: translatedFields.operate.updateCompleted,
      });
    } catch (e) {
      updateSubmenuMutation.reset();
      show({
        type: 'DANGER',
        message: e,
      });
    } finally {
      setDifferenceData([]);
      setCurrentSubmenuItem(undefined);
    }
  }

  function onChangeDetail(item: ISubmenu) {
    setCurrentSubmenuItem(item);
  }

  function onChangeForm(e: ChangeEvent<HTMLInputElement | HTMLSelectElement>) {
    const name = e.target.name;
    const value = e.target.value;

    if (name === 'sort') {
      setForm({ ...form, sort: parseInt(value) });
    } else {
      setForm({ ...form, [name]: value });
    }
  }

  return (
    <Box>
      <div className="vstack gap-4">
        <div className="table-responsive">
          <table className="table table-hover align-middle">
            <thead>
              <tr className="text-nowrap">
                <th scope="col" className="fw-normal">
                  ID
                </th>
                <th scope="col" className="fw-normal">
                  {translatedFields.properties.name}
                </th>
                <th scope="col" className="fw-normal">
                  {translatedFields.properties.path}
                </th>
                <th scope="col" className="fw-normal">
                  {translatedFields.properties.sort}
                </th>
                <th scope="col" className="fw-normal">
                  {translatedFields.properties.menuType}
                </th>
                <th scope="col" className=""></th>
              </tr>
            </thead>
            <tbody>
              {source.submenus.map((item) => {
                return (
                  <tr key={item.id} className="text-nowrap">
                    <td
                      className="cursor-pointer"
                      onClick={onChangeDetail.bind(this, item)}
                    >
                      {item.id}
                    </td>
                    <td
                      className="cursor-pointer"
                      onClick={onChangeDetail.bind(this, item)}
                    >
                      {item.name}
                    </td>
                    <td
                      className="cursor-pointer"
                      onClick={onChangeDetail.bind(this, item)}
                    >
                      {item.path}
                    </td>
                    <td
                      className="cursor-pointer"
                      onClick={onChangeDetail.bind(this, item)}
                    >
                      {item.sort}
                    </td>
                    <td
                      className="cursor-pointer"
                      onClick={onChangeDetail.bind(this, item)}
                    >
                      {translatedFields.enums.menuType[item.menuType]}
                    </td>
                    <td>
                      <button
                        disabled={
                          currentRemoveSubmenuItem &&
                          currentRemoveSubmenuItem.id === item.id &&
                          removeSubmenuMutation.isLoading
                        }
                        onClick={onClickRemove.bind(this, item)}
                        className="btn btn-sm btn-danger"
                        type="button"
                      >
                        {currentRemoveSubmenuItem &&
                        currentRemoveSubmenuItem.id === item.id &&
                        removeSubmenuMutation.isLoading ? (
                          <Spinner classs="me-2" />
                        ) : (
                          <i className="bi bi-trash me-2"></i>
                        )}
                        {translatedFields.operate.delete}
                      </button>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        {source.submenus.length === 0 && <Nodata />}

        <form onSubmit={onSubmit} className="vstack gap-4">
          <div>
            <label className="form-label">
              {translatedFields.properties.name}
            </label>
            <input
              type="text"
              className="form-control"
              name="name"
              value={form.name}
              onChange={onChangeForm}
              aria-describedby="name"
            />
          </div>

          <div>
            <label className="form-label">
              {translatedFields.properties.path}
            </label>
            <input
              type="text"
              className="form-control"
              name="path"
              value={form.path}
              onChange={onChangeForm}
              aria-describedby="path"
            />
          </div>

          <div>
            <label className="form-label">
              {translatedFields.properties.sort}
            </label>
            <input
              type="number"
              className="form-control"
              min={0}
              name="sort"
              value={form.sort}
              onChange={onChangeForm}
              aria-describedby="sort"
            />
          </div>

          <div>
            <label className="form-label">
              {translatedFields.properties.menuType}
            </label>
            <select
              name="menuType"
              value={form.menuType}
              onChange={onChangeForm}
              className="form-select"
            >
              {['LINK', 'BUTTON'].map((item) => {
                return (
                  <option key={item} value={item}>
                    {(translatedFields as any).enums.menuType[item]}
                  </option>
                );
              })}
            </select>
          </div>

          <button
            type="submit"
            disabled={updateSubmenuMutation.isLoading || isDisabledSave}
            className="btn btn-success col col-lg-2 my-4"
          >
            {updateSubmenuMutation.isLoading && <Spinner classs="me-2" />}
            {translatedFields.operate.update}
          </button>
        </form>
      </div>
    </Box>
  );
}
